<?php

class CHCAxis extends AbstractHCObject
{
    private $m_oLabels;
    private $m_aoPlotBands = array();
    private $m_aoPlotLines = array();
    private $m_oTitle;
    private $setTitle;
    
    
    /**
     * Build the axis object
     */
    public function __construct()
    {
        $this->m_oLabels     = new CHCAxisLabels();
        $this->m_oTitle      = new CHCAxisTitle();
        
        $this->setTitle = $this->m_oTitle;
    }
    
    
    /**
     * When using an alternate grid color, a band is painted 
     * across the plot area between every other grid line. 
     * Defaults to null.
     * 
     * @param String $psString
     */
    public function setAlternateGridColor($psColor)
    {
        if (CSDebug::assertHex($psColor)) return false;
        
        $this->setParam('alternateGridColor', $psColor);
    }
    
    
    /**
     * If categories are present for the xAxis, names are used instead of numbers for that axis. Example:
     * 
     * array('Apples', 'Bananas', 'Oranges');
     * 
     * @param Array $pasArray
     */
    public function setCategories($pasArray)
    {
        if (CSDebug::assertArray($pasArray)) return false;
        
        $this->setParam('categories', $pasArray);
    }
    
    
    /**
     * For a datetime axis, the scale will automatically adjust to the appropriate unit. 
     * This member gives the default string representations used for each unit. 
     * For an overview of the replacement codes, see dateFormat. 
     * 
     * Defaults to: 
     * 
	 * array
	 * (
	 * 		second: '%H:%M:%S',
	 * 		minute: '%H:%M',
	 * 		hour: 	'%H:%M',
	 * 		day: 	'%e. %b',
	 * 		week: 	'%e. %b',
	 * 		month: 	'%b '%y',
	 * 		year: 	'%Y'
	 * );
	 * 
     * @param $pasArray
     */
    public function setDateTimeLabelFormats($pasArray) 
    {
        if (CSDebug::assertArray($pasArray)) return false;
        
        $this->setParam('dateTimeLabelFormats', $pasArray);
    }
    
    
    /**
     * Color of the grid lines extending the ticks across the plot area. Defaults to "#C0C0C0".
     *  
     * @param unknown_type $psString
     */
    public function setGridLineColor($psColor='#C0C0C0')
    {
        if (CSDebug::assertHex($psColor)) return false;
        
        $this->setParam('gridLineColor', $psColor);
    }
    
    
    /**
     *  The width of the grid lines extending the ticks across the plot area. Defaults to 0.
     *  
     * @param Integer $pnInteger
     */
    public function setGridLineWidth($pnInteger=0)
    {
        if (CSDebug::assertInteger($pnInteger)) return false;
        
        $this->setParam('gridLineWidth', $pnInteger);
    }
    
    
    /**
     *  Configuration object for the axis labels, usually displaying the number for each tick. 
     *  
     *  @return Object CHCAxisLabels
     * 
	 */
    public function setLabels()
    {
        return $this->m_oLabels;
    }
    
    
    
    /**
     *  The color of the line marking the axis itself. Defaults to "#C0D0E0".
     *  
     * @param String $psColor
     */
    public function setLineColor($psColor='#C0D0E0')
    {
        if (CSDebug::assertHex($psColor)) return false;
        
        $this->setParam('lineColor', $psColor);
    }
    
    
    /**
     * The width of the line marking the axis itself. Defaults to 1.
     *  
     * @param Integer $pnInteger
     */
    public function setLineWidth($pnInteger)
    {
        if (CSDebug::assertInteger($pnInteger)) return false;
        
        $this->setParam('lineWidth', $pnInteger);
    }
    
    
    /**
     *  The maximum value of the axis. 
     *  If null the max value is automatically calculated. 
     *  
     *  Defaults to null.
     *  
     * @param Integer $pnInteger
     */
    public function setMax($pnInteger)
    {
        if (CSDebug::assertInteger($pnInteger, true)) return false;
        
        $this->setParam('max', $pnInteger);
    }
    
    
    /**
     *  The maximum amount of zoom on this axis. 
     *  The entire axis will not be allowed to span over a smaller interval than this. 
     *  For example, for a datetime axis the main unit is milliseconds. 
     *  If maxZoom is set to 3600000, you can't zoom in more than to one hour. 
     *  
     *  Defaults to 1.
     *  
     * @param $pnInteger
     */
    public function setMaxZoom($pnInteger=1)
    {
        if (CSDebug::assertInteger($pnInteger, true)) return false;
        
        $this->setParam('maxZoom', $pnInteger);
    }
    
    
    /**
     * The minimum value of the axis. 
     * If null the min value is automatically calculated. 
     * Defaults to null.
     * 
     * @param $pnInteger
     */
    public function setMin($pnInteger)
    {
        if (CSDebug::assertInteger($pnInteger, true)) return false;
        
        $this->setParam('min', $pnInteger);
    }
    
    
    /**
     * Color of the minor, secondary grid lines. Defaults to #E0E0E0.
     *  
     * @param String $psColor
     */
    public function setMinorGridLineColor($psColor='#E0E0E0')
    {
        if (CSDebug::assertHex($psColor)) return false;
        
        $this->setParam('minorGridLineColor', $psColor);
    }
    
    
    /**
     *  Width of the minor, secondary grid lines. Defaults to 1.
     *  
     * @param Integer $pnInteger
     */
    public function setMinorGridLineWidth($pnInteger=1)
    {
        if (CSDebug::assertInteger($pnInteger, true)) return false;
        
        $this->setParam('minorGridLineWidth', $pnInteger);
    }
    
    
    /**
     *  Color for the minor tick marks. Defaults to #A0A0A0.
     *  
     *  @param $psColor
     */
    public function setMinorTickColor($psColor='#A0A0A0')
    {
        if (CSDebug::assertHex($psColor)) return false;
        
        $this->setParam('minorTickColor', $psColor);
    }
    
    
    /**
     *  Tick interval in scale units for the minor ticks. 
     *  
     *  If "auto", the minor tick interval is calculated as a fifth of the tickInterval. 
     *  If null, minor ticks are not shown. 
     *  
     *  Defaults to null. 
     *  
     * @param $pnInterval
     */
    public function setMinorTickInterval($pnInterval)
    {
        // default 
        if ($pnInterval == 'auto') return true;
        
        if (CSDebug::assertInteger($pnInterval, true)) return false;
        
        $this->setParam('minorTickInterval', $pnInterval);
    }
    
    
    /**
     * The pixel length of the minor tick marks. 
     * 
     * Defaults to 2.
     *  
     * @param Integer $pnNumber
     */
    public function setMinorTickLength($pnNumber=2)
    {
        if (CSDebug::assertNumber($pnNumber, true)) return false;
        
        $this->setParam('minorTickLength', $pnNumber);
    }
    
    
    /**
     *  The position of the minor tick marks relative to the axis line. 
     *  Can be one of inside and outside. 
     *  
     *  Defaults to outside.
     *  
     * @param $psString
     */
    public function setMinorTickPosition($psString='outside')
    {
        if (CSDebug::assertString($psString)) return false;
        if (!in_array($psString, array('inside', 'outside'))) return false;
        
        $this->setParam('minorTickPosition', $psString);
    }
    
    
    /**
     * The pixel width of the minor tick mark. 
     * 
     * Defaults to 1.
     *  
     * @param $pnInteger
     */
    public function setMinorTickWidth($pnInteger=1)
    {
        if (CSDebug::assertInteger($pnInteger, true)) return false;
        
        $this->setParam('minorTickWidth', $pnInteger);
    }
    
    
    /**
     *  The distance in pixels from the plot area to the axis line. 
     *  A positive offset moves the axis with it's line, labels and ticks away from the plot area. 
     *  This is typically used when two or more axes are displayed on the same side of the plot. 
     *  
     *  Defaults to 0.
     *  
     * @param $pnInteger
     */
    public function setOffset($pnInteger=0)
    {
        if (CSDebug::assertInteger($pnInteger, true)) return false;
        
        $this->setParam('offset', $pnInteger);
    }
    
    
    /**
     *  Whether to display the axis on the opposite side of the normal.
     *  The normal is on the left side for vertical axes and bottom for horizontal, 
     *  so the opposite sides will be right and top respectively. 
     *  This is typically used with dual or multiple axes. 
     *  
     *  Defaults to false.
     *  
     * @param unknown_type $pbBoolean
     */
    public function setOpposite($pbBoolean=false)
    {
        if (CSDebug::assertBoolean($pbBoolean)) return false;
        
        $this->setParam('opposite', $pbBoolean);
    }
    

    /**
     *  An array of configuration objects for plot bands colouring parts of the plot area background. 
     *  
     *  Defaults to null.
     *  
     * @param String $psColor
     * @param Number $pnFrom
     * @param Number $pnTo
     */
    public function addPlotBands($psColor, $pnFrom, $pnTo)
    {
        $oPlotBand = new CHCAxisPlotBands();
        $oPlotBand->setColor($psColor);
        $oPlotBand->setFrom($pnFrom);
        $oPlotBand->setTo($pnTo);
        
        $nLength = count($this->m_aoPlotBands);
        
        $this->m_aoPlotBands[$nLength] = $oPlotBand;
    }
    
    
 /**
	 * Alias of $this->addPlotBands()
     */
    public function setPlotBands($psColor, $pnValue, $pnWidth)
    {
        return $this->addPlotBands($psColor, $pnValue, $pnWidth);
    }
    

    /**
     * An array of configuration objects for plot lines marking specific values in the plot area. 
     * 
     * Defaults to null.
     *  
     * @param String $psColor
     * @param Number $pnValue
     * @param Number $pnWidth
     */
    public function addPlotLines($psColor, $pnValue, $pnWidth)
    {
        $nLength = count($this->m_aoPlotLines);
        
        $oPlotLine = new CHCAxisPlotLines();
        $oPlotLine->setColor($psColor);
        $oPlotLine->setValue($pnValue);
        $oPlotLine->setWidth($pnWidth);
        
        $this->m_aoPlotLines[$nLength] = $oPlotLine;
    }
    
    
    
    /**
	 * Alias of $this->addPlotLines()
     */
    public function setPlotLines($psColor, $pnValue, $pnWidth)
    {
        return $this->addPlotLines($psColor, $pnValue, $pnWidth);
    }
    
    
    /**
     *  Whether to reverse the axis so that the highest number is closest to origo. 
     *  If the chart is inverted, the x axis is reversed by default. 
     *  
     *  Defaults to false.
     *  
     * @param $pbBoolean
     */
    public function setReversed($pbBoolean=false)
    {
        if (CSDebug::assertBoolean($pbBoolean)) return false;
        
        $this->setParam('reverse', $pbBoolean);
    }
    
    
    /**
     * Alias of $this->setReversed()
     * @param $pbBoolean
     */
    public function reverse($pbBoolean=false)
    {
        return $this->setReversed($pbBoolean);
    }
    
    
    /**
     *  Whether to show the first tick label. 
     *  
     *  Defaults to true.
     *  
     * @param $pbBoolean
     */
    public function setShowFirstLabel($pbBoolean=true)
    {
        if (CSDebug::assertBoolean($pbBoolean)) return false;
        
        $this->setParam('showFirstLabel', $pbBoolean);
    }
    
    
    /**
     * Alias of $this->setShowFirstLabel()
     * @param $pbBoolean
     */
    public function showFirstLabel($pbBoolean=false)
    {
        return $this->setShowFirstLabel($pbBoolean);
    }
    
    
    /**
     *  Whether to show the last tick label. 
     *  
     *  Defaults to false.
     *  
     * @param $pbBoolean
     */
    public function setShowLastLabel($pbBoolean=false)
    {
        if (CSDebug::assertBoolean($pbBoolean)) return false;
        
        $this->setParam('showLastLabel', $pbBoolean);
    }
    
    
    /**
     * Alias of $this->setShowLastLabel()
     * @param Boolean $pbBoolean
     */
    public function showLastLabel($pbBoolean=false)
    {
        return $this->setShowLastLabel($pbBoolean);
    }
    
    
    /**
     *  For datetime axes, this decides where to put the separator line between weeks. 
     *  
     *  0 = Sunday, 
     *  1 = Monday. 
     *  
     *  Defaults to 1.
     *  
     * @param Integer $pnInteger
     */
    public function setStartOfWeek($pnInteger=1)
    {
        if (CSDebug::assertInteger($pnInteger)) return false;
        
        $this->setParam('startOfWeek', $pnInteger);
    }
    
    
    /**
     *  Color for the main tick marks. 
     *  
     *  Defaults to #C0D0E0.
     *  
     * @param $psColor
     */
    public function setTickColor($psColor='#C0D0E0')
    {
        if (CSDebug::assertHex($psColor)) return false;
        
        $this->setParam('tickColor', $psColor);
    }
    
    
    /**
     *  The interval of the tick marks in axis units. 
     *  When "auto", the tick interval is computed to approximately follow the tickPixelInterval. 
     *  Not applicable to categorized axis. 
     *  
     *  Defaults to "auto".
     *  
     * @param Mixed $pnInterval
     */
    public function setTickInterval($pnInterval)
    {
        // default 
        if ($pnInterval == 'auto') return true;
        
        if (CSDebug::assertInteger($pnInterval, true)) return false;
        
        $this->setParam('tickInterval', $pnInterval);
    }
    
    
    /**
     *  The pixel length of the main tick marks. 
     *  
     *  Defaults to 5.
     *  
     * @param $pnNumber
     */
    public function setTickLength($pnNumber=5)
    {
        if (CSDebug::assertNumber($pnNumber, true)) return false;
        
        $this->setParam('minorTickLength', $pnNumber);
    }
    
    
    /**
     *  For categorized axes only. 
     *  If "on" the tick mark is placed in the center of the category, 
     *  if "between" the tick mark is placed between categories. 
     *  
     *  Defaults to "between".
     *  
     * @param String $psString
     */
    public function setTickmarkPlacement($psString='outside')
    {
        if (CSDebug::assertString($psString)) return false;
        if (!in_array($psString, array('on', 'between'))) return false;
        
        $this->setParam('tickmarkPlacement', $psString);
    }
    

    /**
     *  If tickInterval is "auto" this option sets the approximate pixel interval of the tick marks. 
     *  Not applicable to categorized axis. 
     *  
     *  Defaults to 72 for the Y axis and 100 for the X axis. 
     * @param $pnInterval
     */
    public function setTickPixelInterval($pnInterval=72)
    {
         // default 
        if ($pnInterval == 'auto') return true;
        
        if (CSDebug::assertNumber($pnInterval, true)) return false;
        
        $this->setParam('tickPixelInterval', $pnInterval);
    }
    
    
    /**
     *  The position of the major tick marks relative to the axis line. 
     *  Can be one of inside and outside. 
     *  
     *  Defaults to "outside".
     *  
     * @param $psString
     */
    public function setTickPosition($psString='outside')
    {
        if (CSDebug::assertString($psString)) return false;
        if (!in_array($psString, array('inside', 'outside'))) return false;
        
        $this->setParam('tickPosition', $psString);
    }
    
    
    /**
     *  The pixel width of the major tick marks. 
     *  
     *  Defaults to 1.
     *  
     * @param $pnInteger
     */
    public function setTickWidth($pnInteger=1)
    {
        if (CSDebug::assertInteger($pnInteger, true)) return false;
        
        $this->setParam('tickWidth', $pnInteger);
    }
    
    
    /**
     *  Configuration object for the axis title. 
     *  
     *  @return CHCAxisTitle
     */
    public function setTitle($psText)
    {
        $this->m_oTitle->setText($psText);
    }
    
    
    /**
     *  The type of axis. Can be one of "linear" or "datetime". 
     *  In a datetime axis, the numbers are given in milliseconds, 
     *  and tick marks are placed on appropriate values like full hours or days. 
     *  
     *  Defaults to "linear".
     *  
     * @param $psString
     */
    public function setType($psString)
    {
        if (CSDebug::assertString($psString)) return false;
        if (!in_array($psString, array('linear', 'datetime'))) return false;
        
        $this->setParam('type', $psString);
    }
    
    
    public function getData()
    {
        $asPlotLines = array();
        foreach ($this->m_aoPlotLines as $oPlotLine)
            $asPlotLines[] = $oPlotLine->getData();
            
        $asPlotBands = array();
        foreach ($this->m_aoPlotBands as $oPlotBand)
            $asPlotBands[] = $oPlotBand->getData();
        
        $asLabels = $this->m_oLabels->getData();
        
        if (!empty($asLabels))
            $this->setParam('labels', $asLabels);
        
        if (!empty($asPlotBands))
            $this->setParam('plotBands', $asPlotBands);
            
        if (!empty($asPlotLines))
            $this->setParam('ploLines',  $asPlotLines);
            
        $this->setParam('title',     $this->m_oTitle->getData());
        
        return parent::getData();
    }
}

?>